/**
 * Copyright (c) 2008 Luciano Bustos - riaevolution.com, All Rights Reserved.
 * 
 * Contact luchyx@riaevolution.com
 *
 * See www.riaevolution.com
 * See www.riaevolution.com/blog
 *  
 * Permission is hereby granted, free of charge, to any person obtaining a copy of 
 * this software and associated documentation files (the "Software"), to deal in 
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do
 * so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all 
 * copies or substantial portions of the Software.
 * 
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 * */
package com.riaevolution.utils {
	import mx.formatters.DateFormatter;
	public class DateFunction {
		/**
		dateDiff(datePart:String, date1:Date, finalDate:Date):Number<BR>
		returns the difference between 2 dates<BR>
		valid dateParts:<BR>
		s: Seconds<BR>
		n: Minutes<BR>
		h: Hours<BR>
		d: Days<BR>
		m: Months<BR>
		y: Years<BR>
		*/
		public static function dateDiff(datePart:String, intialDate:Date, finalDate:Date):Number{
			return getDatePartHashMap()[datePart.toLowerCase()](intialDate,finalDate);
		}
		private static function getDatePartHashMap():Object{
			var dpHashMap:Object = new Object();
			dpHashMap["s"] = getSeconds;
			dpHashMap["n"] = getMinutes;
			dpHashMap["h"] = getHours;
			dpHashMap["d"] = getDays;
			dpHashMap["m"] = getMonths;
			dpHashMap["y"] = getYears;
			return dpHashMap;
		}
		public static function SQLDate(d:Date):String{
			//SQLDATEFormatter:
			//1981-10-05
			var SQLDateFormat:String = "YYYYYY-MM-DD";
			var SQLDATEFormatter:DateFormatter = new DateFormatter();
			SQLDATEFormatter.formatString = SQLDateFormat;
			return SQLDATEFormatter.format(d);
		}
		public static function fromSQLDate(d:String):Date{
			var date_str:String = new String(d);
			var date : Array = date_str.split("-");
			if(date_str == null){
				return null;
			}
			return  new Date(date[0],date[1]-1,date[2]);
		}
		private static function compareDates(intialDate:Date, finalDate:Date):Number{
			return intialDate.getTime() - finalDate.getTime();
		}
		private static function getSeconds(intialDate:Date, finalDate:Date):Number{
			return Math.floor(compareDates(intialDate,finalDate)/1000);
		}
		private static function getMinutes(initialDate:Date, finalDate:Date):Number{
			return Math.floor(getSeconds(initialDate,finalDate)/60);
		}
		private static function getHours(initialDate:Date, finalDate:Date):Number{
			return Math.floor(getMinutes(initialDate,finalDate)/60);
		}
		private static function getDays(initialDate:Date, finalDate:Date):Number{
			return Math.floor(getHours(initialDate,finalDate)/24);
		}
		private static function getMonths(initialDate:Date, finalDate:Date):Number{
			var yearDiff  :Number= getYears(initialDate,finalDate);
			var monthDiff :Number = initialDate.getMonth() - finalDate.getMonth();
			if(monthDiff < 0){
			monthDiff += 12;
			}
			if(initialDate.getDate()< finalDate.getDate()){
			monthDiff -=1;
			}
			return 12 *yearDiff + monthDiff;
		}
		private static function getYears(initialDate:Date, finalDate:Date):Number{
			return Math.floor(getDays(initialDate,finalDate)/365);
		}
		public static function DateDifference (initialDate:Date, finalDate:Date):Difference {
			var state :String = new String();
			if (finalDate < initialDate) { state = "past" } else { state = "future"}
			if (finalDate == initialDate) {state = "present"}
			var d1 :Number = Math.max(initialDate.valueOf(), finalDate.valueOf());
			var d2 :Number = Math.min(initialDate.valueOf(), finalDate.valueOf());
			var dt :Number = d1 - d2;
			// weeks
			var w :Number= Math.floor (dt / 1000 / 60 / 60 / 24 / 7);
			dt -= w * 1000 * 60 * 60 * 24 * 7;
			// days
			var d :Number= Math.floor (dt / 1000 / 60 / 60 / 24);
			dt -= d * 1000 * 60 * 60 * 24;
			// hours
			var h :Number= Math.floor (dt / 1000 / 60 / 60);
			dt -= h * 1000 * 60 * 60;
			//minutes
			var m:Number = Math.floor (dt / 1000 / 60);
			dt -= m * 1000 * 60;
			// seconds
			var s :Number= Math.floor (dt / 1000);
			var dif:Difference = new Difference();
			dif.months = Math.floor(w/4);
			dif.weeks = w;
			dif.days = d;
			dif.hours = h;
			dif.minutes = m;
			dif.seconds = s;
			dif.state = state;
			return dif;
		}
	}
}